package summarizer.newversion;

import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;

import thesis.DataUtil;
import thesis.FSModule;
import thesis.InfoUnit;
import thesis.DataObject;
import thesis.Summary;

public class DivSummarizer extends Summarizer {
	private final double alpha;
	private final double beta;
	private final double gamma;
	private final double[][] probs;
	private final ArrayList<InfoUnit> infoUnits;
	private HashMap<Long, DataObject> memoryTweets;
	private double totalInfo = 1;

	public DivSummarizer(double[][] probs, ArrayList<InfoUnit> infoUnits,
			double alpha, double beta, double gamma) {
		this.alpha = alpha;
		this.beta = beta;
		this.gamma = gamma;

		this.probs = probs;
		this.infoUnits = infoUnits;
	}

	private DataObject preprocess(Summary summary, int K, int dimSize) {
		// find tweet with best quality
		DataObject bestT = null;
		double bestScore = -1;
		for (DataObject t : memoryTweets.values()) {
			double coverage = 0;
			double score = t.getQuality();
			if (score > bestScore) {
				bestScore = score;
				bestT = t;
			}
			t.setDiv(1);
		}
		summary.addMemoryTweet(bestT);
		this.memoryTweets.remove(bestT.getDbId());
		return bestT;
	}

	private void greedProcess(int K, int numberOfPages, Summary summary,
			DataObject bestT) {
		List<DataObject> tweetsInS = summary.getMemoryTweets();
		while (tweetsInS.size() < K) {
			double bestScore = -1;
			DataObject prevT = bestT;
			for (DataObject t : this.memoryTweets.values()) {
				// compute quality for tweet t
				double quality = 0;
				for (DataObject tInS : tweetsInS) {
					quality += tInS.getQuality();
				}
				quality = (quality + t.getQuality()) / (tweetsInS.size() + 1);
				t.setQual(quality);
				// compute diversity after adding t to summary
				t.setDiv(Math.min(Math.min(t.getDiv(), prevT.getDiv()),
						DataUtil.dist(t, prevT)));
				// get summary score
				double summaryScore = alpha * quality + beta * t.getDiv();
				if (summaryScore > bestScore) {
					bestScore = summaryScore;
					bestT = t;
				}
			}
			tweetsInS.add(bestT);
			this.memoryTweets.remove(bestT.getDbId());
			// System.out.println("Summary size: " + tweetsInS.size());
			// System.out.println("Quality: " + bestT.getQual() + " Diversity: "
			// + bestT.getDiv() + " Coverage: " + bestT.getCov());
		}
	}

	public Summary computeSummary(int summaryDimension, int numberOfPages,
			HashMap<Long, DataObject> tweets, int dimSize) {
		this.memoryTweets = tweets;
		Summary summary = new Summary();
		if (summaryDimension <= 0 || this.memoryTweets.isEmpty()) {
			return summary;
		}
		executionTime = (new GregorianCalendar()).getTimeInMillis();
		DataObject bestT = preprocess(summary, summaryDimension, dimSize);
		greedProcess(summaryDimension, numberOfPages, summary, bestT);
		executionTime = (new GregorianCalendar()).getTimeInMillis()
				- executionTime;
		return summary;
	}

	public String toString() {
		return "Div Summarizer <" + alpha + " " + beta + " " + gamma + ">";
	}

	public long getExecutionTime() {
		return executionTime;
	}
}
